/* eslint-disable */
import Node from './node'
import Edge from './edge'
import Anchor from './anchor'

export default class Graph {
  constructor(options = {}) {
    this.container = options.container
    this.nodes = new Map()
    this.edges = new Map()
    this.panOffset = { x: 0, y: 0 }
    this.scale = 1
    // 添加事件系统
    this.events = {}

    // 初始化节点
    if (options.nodes) {
      options.nodes.forEach(node => {
        this.addNode(node)
      })
    }

    // 初始化边
    if (options.edges) {
      options.edges.forEach(edge => {
        this.addEdge(edge)
      })
    }
  }

  // 添加事件监听
  on(eventName, callback) {
    if (!this.events[eventName]) {
      this.events[eventName] = []
    }
    this.events[eventName].push(callback)
  }

  // 触发事件
  emit(eventName, data) {
    if (this.events[eventName]) {
      this.events[eventName].forEach(callback => {
        callback(data)
      })
    }
  }

  // 添加节点
  addNode(node) {
    if (!(node instanceof Node)) {
      node = new Node(node)
    }
    this.nodes.set(node.id, node)
    // 触发节点添加事件
    this.emit('nodeAdded', node)
    return node
  }

  // 删除节点
  removeNode(nodeId) {
    const node = this.nodes.get(nodeId)
    if (node) {
      // 删除相关边
      this.edges.forEach((edge, id) => {
        if (edge.sourceNodeId === nodeId || edge.targetNodeId === nodeId) {
          this.edges.delete(id)
          this.emit('edgeRemoved', edge)
        }
      })
      this.nodes.delete(nodeId)
      // 触发节点删除事件
      this.emit('nodeRemoved', node)
    }
    return node
  }

  // 设置节点
  setNodes(nodes) {
    this.nodes.clear()
    nodes.forEach(node => {
      this.addNode(node)
    })
  }

  // 设置边
  setEdges(edges) {
    this.edges.clear()
    edges.forEach(edge => {
      this.addEdge(edge)
    })
  }

  // 更新节点位置
  updateNodePosition(nodeId, x, y) {
    const node = this.nodes.get(nodeId)
    if (node) {
      node.x = x
      node.y = y
      // 更新相关边
      this.edges.forEach(edge => {
        if (edge.sourceNodeId === nodeId || edge.targetNodeId === nodeId) {
          edge.updatePath(this.nodes)
        }
      })
    }
    return node
  }

  // 获取节点
  getNode(nodeId) {
    return this.nodes.get(nodeId)
  }

  // 根据位置获取节点
  getNodeAtPosition(x, y) {
    let foundNode = null
    this.nodes.forEach(node => {
      if (
        x >= node.x &&
        x <= node.x + node.width &&
        y >= node.y &&
        y <= node.y + node.height
      ) {
        foundNode = node
      }
    })
    return foundNode
  }

  // 添加边
  addEdge(edge) {
    if (!(edge instanceof Edge)) {
      edge = new Edge(edge)
    }
    edge.updatePath(this.nodes)
    this.edges.set(edge.id, edge)
    // 添加边添加事件
    this.emit('edgeAdded', edge)
    return edge
  }

  // 删除边
  removeEdge(edgeId) {
    const edge = this.edges.get(edgeId)
    if (edge) {
      this.edges.delete(edgeId)
      // 添加边删除事件
      this.emit('edgeRemoved', edge)
    }
    return edge
  }

  // 获取边
  getEdge(edgeId) {
    return this.edges.get(edgeId)
  }

  // 选择节点
  selectNode(nodeId) {
    this.clearSelection()
    const node = this.nodes.get(nodeId)
    if (node) {
      node.selected = true
    }
  }

  // 选择边
  selectEdge(edgeId) {
    this.clearSelection()
    const edge = this.edges.get(edgeId)
    if (edge) {
      edge.selected = true
    }
  }

  // 清除选择
  clearSelection() {
    this.nodes.forEach(node => {
      node.selected = false
    })
    this.edges.forEach(edge => {
      edge.selected = false
    })
  }

  // 获取选中的节点
  getSelectedNodes() {
    return Array.from(this.nodes.values()).filter(node => node.selected)
  }

  // 获取选中的边
  getSelectedEdges() {
    return Array.from(this.edges.values()).filter(edge => edge.selected)
  }

  // 平移
  pan(dx, dy) {
    this.panOffset.x += dx
    this.panOffset.y += dy
  }

  // 缩放
  zoom(scale) {
    this.scale = scale
  }

  // 居中显示
  fitView() {
    // 计算所有节点的边界
    if (this.nodes.size === 0) return

    let minX = Infinity
    let minY = Infinity
    let maxX = -Infinity
    let maxY = -Infinity

    this.nodes.forEach(node => {
      minX = Math.min(minX, node.x)
      minY = Math.min(minY, node.y)
      maxX = Math.max(maxX, node.x + node.width)
      maxY = Math.max(maxY, node.y + node.height)
    })

    // 计算中心点
    const centerX = (minX + maxX) / 2
    const centerY = (minY + maxY) / 2

    // 计算容器中心
    const rect = this.container.getBoundingClientRect()
    const containerCenterX = rect.width / 2
    const containerCenterY = rect.height / 2

    // 平移以居中
    this.panOffset.x = containerCenterX - centerX
    this.panOffset.y = containerCenterY - centerY

    // 计算缩放比例
    const width = maxX - minX
    const height = maxY - minY
    const scaleX = rect.width / width * 0.8
    const scaleY = rect.height / height * 0.8
    this.scale = Math.min(scaleX, scaleY)
  }

  // 清空画布
  clear() {
    this.nodes.clear()
    this.edges.clear()
    this.panOffset = { x: 0, y: 0 }
    this.scale = 1
  }

  // 导出数据
  exportData() {
    return {
      nodes: Array.from(this.nodes.values()).map(node => node.toJSON()),
      edges: Array.from(this.edges.values()).map(edge => edge.toJSON())
    }
  }

  // 导入数据
  importData(data) {
    this.clear()
    if (data.nodes) {
      data.nodes.forEach(node => {
        this.addNode(node)
      })
    }
    if (data.edges) {
      data.edges.forEach(edge => {
        this.addEdge(edge)
      })
    }
    this.fitView()
  }
}